package com.hxs.learn.shiro.realm;

import com.hxs.learn.common.web.HttpContext;
import com.hxs.learn.common.web.LoginInfo;
import com.hxs.learn.entity.core.SysUser;
import com.hxs.learn.service.core.SysRoleMenuPermissionService;
import com.hxs.learn.service.core.SysRoleService;
import com.hxs.learn.service.core.SysUserService;
import com.hxs.learn.shiro.jwt.JwtUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author huxinsheng
 */
@Component
public class MyFormRealm extends BaseRealm {
    private final SysUserService userRepository;
    private final SysRoleService roleService;
    private final SysRoleMenuPermissionService roleMenuPermissionService;
    private final JwtUtil jwtUtil;

    @Autowired
    public MyFormRealm(SysUserService userRepository, SysRoleService roleService,
                       SysRoleMenuPermissionService roleMenuPermissionService, JwtUtil jwtUtil) {
        this.userRepository = userRepository;
        this.roleService = roleService;
        this.roleMenuPermissionService = roleMenuPermissionService;
        this.jwtUtil = jwtUtil;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String loginName = (String) upToken.getPrincipal();

        if (loginName == null) {
            return null;
        }

        SysUser user = userRepository.findByLoginName(upToken.getUsername());

        if (user != null) {
            if (2 == user.getStatus()) {
                throw new LockedAccountException("账户已冻结");
            }

            String accessToken = jwtUtil.generateToken(user);
            LoginInfo loginInfo = new LoginInfo();

            loginInfo.setUserId(user.getId());
            loginInfo.setLoginName(user.getLoginName());
            loginInfo.setRealName(user.getRealName());
            loginInfo.setToken(accessToken);
            loginInfo.setIpAddr(HttpContext.getIpAddr());

            return new SimpleAccount(loginInfo, user.getCredentials(), getName());
        }

        return null;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        LoginInfo user = (LoginInfo) principals.getPrimaryPrincipal();

        return super.initPermission(roleService, roleMenuPermissionService, user.getUserId());
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
